<?php
function getCategories() {
	$query = "SELECT id, name FROM categories";
	$result = mysql_query($query);
	
	$cats = array();
	while($row = mysql_fetch_array($result)) {
		$cats[] = array($row[0], $row[1]);
	}	
	return $cats;
}


//TRUE: success; -1: field left blank; -2: description too short; -3: category does not exist
//-4: cost is out of bounds; -5: description too long
function postItem($user_id, $item_name, $item_description, $category_id, $cost, $method = 0) {
	$user_id = escape($user_id);
	$item_name = escape($item_name);
	$item_description = escape($item_description);
	$category_id = escape($category_id);
	$method = escape($method);
	
	//validate name, description
	if(strlen($item_name) == 0) {
		return -1;
	}
	
	if(strlen($item_description) < 10) {
		return -2;
	}
	
	if(strlen($item_description) > 10000) {
		return -5;
	}
	
	//process cost into an integer
	$cost = round($cost * 100);
	
	//validate cost
	if($cost <= 0 || $cost > 10000) {
		return -4;
	}
	
	//make sure category exists
	$result = mysql_query("SELECT COUNT(*) FROM categories WHERE id = '$category_id'");
	$row = mysql_fetch_array($result);
	
	if($row[0] != 1) {
		return -3;
	}
	
	$cost = escape($cost);
	
	//looks good
	mysql_query("INSERT INTO items (name, description, category_id, seller_id, buyer_id, cost, status, method) VALUES ('$item_name', '$item_description', '$category_id', '$user_id', NULL, '$cost', '0', '$method')");
	return true;
}

//return type: array(status, transaction id) (transaction_id might be false on failure)
//true: success
//-1: invalid type specified
//-2: not enough funds
//-3: no such user?
//-4: database error
function transaction($user_id, $type, $amount, $context) {
	$user_id = escape($user_id);
	$amount = escape($amount);
	$context = escape($context);
	
	//types
	// 0: credit user
	// 1: withdraw user
	if($type !== 0 && $type !== 1) {
		return array(-1, false);
	}
	
	//add into the transactions table
	$result = mysql_query("INSERT INTO transactions (type, user_id, amount, status, context) VALUES ('$type', '$user_id', '$amount', 'posted', '$context')");
	
	if($result === false) {
		return array(-4, false);
	}
	
	$transaction_id = mysql_insert_id();
	
	//verify buyer has enough funds depending on type
	if($type == 1) {
		$result = mysql_query("SELECT credits FROM users WHERE id = '$user_id'");
		
		if($row = mysql_fetch_array($result)) {
			if($row[0] < $amount) {
				mysql_query("UPDATE transactions SET status = 'not enough user funds' WHERE id = '$transaction_id'");
				return array(-2, $transaction_id);
			}
		} else {
			mysql_query("UPDATE transactions SET status = 'failed to check user funds' WHERE id = '$transaction_id'");
			return array(-3, $transaction_id);
		}
	}
	
	//update buyer's funds (let database handle concurrency checks)
	$operator = $type == 0 ? '+' : '-'; //select operator depending on type
	$result = mysql_query("UPDATE users SET credits = credits $operator '$amount' WHERE id = '$user_id'");
	
	if($result === false) {
		//transaction failed
		mysql_query("UPDATE transactions SET status = 'failed to update user credits' WHERE id = '$transaction_id'");
		return array(-4, $transaction_id);
	}
	
	//consistency check on buyer's funds, but only if we withdrew credits
	if($type == 1) {
		$result = mysql_query("SELECT credits FROM users WHERE id = '$user_id'");
		if($row = mysql_fetch_array($result)) {
			if($row[0] < 0) {
				//uh oh, this isn't good... better reverse the transaction and say not enough funds
				mysql_query("UPDATE users SET credits = credits + '$amount' WHERE id = '$user_id'");
				mysql_query("UPDATE transactions SET status = 'fatal: no longer enough funds?' WHERE id = '$transaction_id'");
				return array(-2, $transaction_id);
			}
		} else {
			//this should never happen, so credit this user back even though he/she may not exist
			if($type == 1) {
				mysql_query("UPDATE users SET credits = credits + '$amount' WHERE id = '$user_id'");
			}
		
			mysql_query("UPDATE transactions SET status = 'fatal: user no longer exists?' WHERE id = '$transaction_id'");
			return array(-3, $transaction_id);
		}
	}
	
	//ok, looks like everything is good
	mysql_query("UPDATE transactions SET status = 'completed' WHERE id = '$transaction_id'");
	return true;
}

//true: success; -1: item does not exist; -2: item is no longer available for purchase
//-3: internal error; -4: not enough funds; -5: cannot buy your own item
function purchaseItem($user_id, $item_id) {
	$user_id = escape($user_id);
	$item_id = escape($item_id);
	
	//verify item exists, and its status; and grab its cost
	$result = mysql_query("SELECT status, cost, name, seller_id FROM items WHERE id = '$item_id'");
	$item_name = 0;
	$item_seller = 0;
	$cost = 0;
	
	if($row = mysql_fetch_array($result)) {
		if($row[0] != 0) {
			return -2;
		} else {
			$cost = $row[0];
			$item_name = $row[1];
			$item_seller = $row[2];
		}
	} else {
		return -1;
	}
	
	//sanity check: can't buy your own item
	if($item_seller == $user_id) {
		return -5;
	}
	
	//conduct buyer transaction to us; 1 means withdraw
	$result = transaction($user_id, 1, $amount, "purchase for item_id=$item_id");
	
	if($result[0] == -1) { //invalid type
		return -3;
	} else if($result[0] == -2) { //no funds
		return -4;
	} else if($result[0] == -3) { //no such user
		return -3;
	} else if($result[0] == -4) { //database error
		return -3;
	} else if($result[0] != true) {
		return -3;
	}
	
	//transaction went through, now set the buyer on the item
	mysql_query("UPDATE items SET status = '1', buyer_id = '$user_id', cost = '$amount' WHERE status = '0' AND id = '$item_id'");
	
	//make sure we found a row
	if(mysql_affected_rows() == 0) {
		//shit, looks like someone stole our item
		//credit the user back
		transaction($user_id, 0, $amount, "reimbursement for item_id=$item_id (purchase failed)");
		return -2;
	}
	
	//great, looks like we bought it correctly
	
	//email buyer
	$result = mysql_query("SELECT name, email FROM users WHERE id = '$user_id'");
	$buyer_name = "unknown";
	
	if($row = mysql_fetch_array($result)) {
		$buyer_name = $row[0];
		
		$content = 'Hi $NAME$,<br /><br />This is a notification that you have bought "$ITEM_NAME$" (item ID is $ITEM_ID$) for $CREDITS$ credits on The Campus List. If you did not make this transaction, contact us immediately. Otherwise, no further action is necessary.<br /><br />Thanks,<br />- The Campus List administrators';
		$content = str_replace('$NAME$', $buyer_name, $content);
		$content = str_replace('$ITEM_NAME$', $item_name, $content);
		$content = str_replace('$ITEM_ID$', $item_id, $content);
		$content = str_replace('$CREDITS$', $cost, $content);
	
		$result = market_mail("Transaction for $item_name", $content, $row[1]);
	}
	
	//now notify the seller that their item has been bought
	$result = mysql_query("SELECT name, email FROM users WHERE id = '" . escape($item_seller) . "'");
	
	if($row = mysql_fetch_array($result)) {
		$content = 'Hi $NAME$,<br /><br />This is a notification that your item, "$ITEM_NAME$" (item ID is $ITEM_ID$) for $CREDITS$ credits, has been purchased by $BUYER_NAME$ on The Campus List. You should get the item to the buyer as soon as possible!<br /><br />Thanks,<br />- The Campus List administrators';
		$content = str_replace('$NAME$', $row[0], $content);
		$content = str_replace('$ITEM_NAME$', $item_name, $content);
		$content = str_replace('$ITEM_ID$', $item_id, $content);
		$content = str_replace('$CREDITS$', $cost, $content);
		$content = str_replace('$BUYER_NAME$', $buyer_name, $content);
	
		$result = market_mail("Purchase notifiction for $item_name", $content, $row[1]);
	}
	
	//great
	return true;
}

//returns array(transaction id, type (0=credit, 1=withdraw), amount (cents), status, context)
function getTransactions($user_id, $start = 0) {
	//return list of transactions starting from $start
	$user_id = escape($user_id);
	$start = intval($start);
	
	$result = mysql_query("SELECT id, type, amount, status, context FROM transactions WHERE user_id = '$user_id' ORDER BY id DESC LIMIT $start, 50");
	$transactions = array();
	
	while($row = mysql_fetch_array($result)) {
		$transactions[] = array($row[0], $row[1], $row[2], $row[3], $row[4]);
	}
	
	return $transactions;
}


//returns list of items we're involved in (buying/selling)
//each element is array(item id, item name, item cost, item status, seller name, buyer name, our involvement (0=selling, 1=buying))
//item status: 0 is no purchase yet, 1 is purchase posted, 2 is purchase authorized, 3 is completed
function getItems($user_id, $start = 0) {
	$user_id = escape($user_id);
	$start = intval($start);
	
	$result = mysql_query("SELECT items.id, items.name, items.cost, items.status, items.seller_id, items.buyer_id, seller.name, buyer.name FROM items LEFT JOIN users AS seller ON seller.id = items.seller_id LEFT JOIN users AS buyer ON buyer.id = items.buyer_id WHERE items.buyer_id = '$user_id' OR items.seller_id = '$user_id' ORDER BY items.id DESC LIMIT $start, 20");
	$items = array();
	
	while($row = mysql_fetch_array($result)) {
		$involvement = $row[4] == $user_id ? 0 : 1; //whether we are the seller; otherwise probably buyer
		$items[] = array($row[0], $row[1], $row[2], $row[3], $row[6], $row[7], $involvement);
	}
	
	return $items;
}

//gets information on one item
//returns array(return type, return value)
//return type
// false: failed
// 0: public item
// 1: selling this item
// 2: buying this item
//return value for false
// 0
//return value for 0
// array(item name, description, category name, cost, seller id, seller name)
//return value for 1/2
// array(item name, description, category name, cost, seller id, seller name, status)
function getItem($item_id, $user_id = 0) {
	$item_id = escape($item_id);
	$user_id = escape($user_id);
	
	//first try to find items with us as buyer
	$status = false;
	$result = mysql_query("SELECT items.name, items.description, categories.name, items.cost, items.seller_id, items.status FROM items LEFT JOIN categories ON categories.id = items.category_id WHERE items.id = '$item_id' AND buyer_id = '$user_id'");
	
	if(mysql_num_rows($result) == 0) {
		//oops, try us as seller
		$result = mysql_query("SELECT items.name, items.description, categories.name, items.cost, items.seller_id, items.status FROM items LEFT JOIN categories ON categories.id = items.category_id WHERE items.id = '$item_id' AND seller_id = '$user_id'");
		
		if(mysql_num_rows($result) == 0) {
			//oops, try a public item
			$result = mysql_query("SELECT items.name, items.description, categories.name, items.cost, items.seller_id FROM items LEFT JOIN categories ON categories.id = items.category_id WHERE items.id = '$item_id' AND status = '0'");
			
			if(mysql_num_rows($result) > 0) {
				$status = 0;
			}
		} else {
			$status = 1;
		}
	} else {
		$status = 2;
	}
	
	if($status === false) {
		return array(false, 0);
	} else {
		if($row = mysql_fetch_array($result)) {
			$seller_name = $row[0];
		}
		//try to get seller name
		$seller_id = escape($row[4]);
		$result = mysql_query("SELECT name FROM users WHERE id = '$seller_id'");
		$seller_name = "Unknown";
		
		if($call = mysql_fetch_array($result)) {
			$seller_name = $call[0];
		}
		
		$return_value = array($row[0], $row[1], $row[2], $row[3], $seller_id, $seller_name);
		
		if($status == 1 || $status == 2) {
			$return_value[] = $row[5];
		}
		
		return array($status, $return_value);
	}
}

//this is called by buyer when he has received the item
// then the payment for the item will be sent to the seller
//true: success
//-1: no such item
function authorizeItem($user_id, $item_id) {
	$user_id = escape($user_id);
	$item_id = escape($item_id);
	
	//update the status
	mysql_query("UPDATE items SET status = '2' WHERE buyer_id = '$user_id' AND id = '$item_id' AND status = '1'");
	
	if(mysql_affected_rows() > 0) {
		//grab the name and cost for reimbursement and emails
		$result = mysql_query("SELECT name, cost, seller_id, method FROM items WHERE id = '$item_id'");
		
		if($row = mysql_fetch_array($result)) {
			$item_name = $row[0];
			$cost = $row[1];
			$seller_id = $row[2];
			$method = $row[3];
			
			//reimburse the seller
			if($method == 0) {
				transaction($seller_id, 1, $cost, "purchase item_id=$item_id completed");
			} else {
				//TODO: pay via paypal
			}
			
			//email the seller
			$content = 'Hi,<br /><br />Your payment for the purchase of $ITEM_NAME$ has been authorized. You have received $CREDITS$ credits to your account. If you opted for this to be sent as money through Paypal, you should receive a payment shortly.<br /><br />Thanks,<br />- The Campus List administrators';
			$content = str_replace('$ITEM_NAME$', $item_name, $content);
			$content = str_replace('$CREDITS$', $cost, $content);
	
			$result = market_mail("Payment for $item_name", $content, $email);
		} else {
			//this is very bad! we can't find the item that we just found earlier
			//this means that seller doesn't get the money for now
			//but we have record so we can reimburse later
			//of course, this should never happen anyway
			return -1;
		}
	} else {
		return -1;
	}
}

function updateKey($item_id, $key) {
	$item_id = escape($item_id);
	$key = escape($key);
	
	mysql_query("UPDATE items set paypal_key='$key' WHERE id=$item_id AND status='0'");
	
}
?>
